Skip to content

08 模块与包

一个文件写了几百行代码?该拆成模块了。多个模块有关系?该组织成包了。Python的模块系统让你把代码拆成多个文件,用import按需导入。

一、模块基础

1.1 什么是模块

一个.py文件就是一个模块。模块可以定义函数、类和变量。

python
# mymodule.py
def greet(name):
    return f"Hello, {name}!"

PI = 3.14159

1.2 导入模块

python
>>> import mymodule
>>> mymodule.greet("World")
'Hello, World!'
>>> mymodule.PI
3.14159

1.3 from...import

python
>>> from mymodule import greet, PI
>>> greet("World")
'Hello, World!'
>>> PI
3.14159

1.4 导入所有名称

python
>>> from mymodule import *

不推荐,会导入模块里所有不以_开头的名称,容易造成命名冲突。模块可以用__all__列表控制import *导入哪些名称:

python
# mymodule.py
__all__ = ['greet', 'PI']

二、模块搜索路径

2.1 搜索顺序

导入模块时,Python按以下顺序查找:

  1. 当前目录
  2. PYTHONPATH环境变量指定的目录
  3. 标准库目录
  4. 第三方包目录(site-packages

2.2 sys.path

python
>>> import sys
>>> sys.path
['', '/usr/lib/python3.14', '/usr/lib/python3.14/lib-dynload', ...]

sys.path是一个列表,可以修改它来添加自定义搜索路径。

三、__name__变量

3.1 模块名

每个模块都有__name__属性:

python
# mymodule.py
print(__name__)  # 输出: mymodule

3.2 main

当模块被直接运行时,__name__等于'__main__'

python
# mymodule.py
def main():
    print("模块被直接运行")

if __name__ == '__main__':
    main()

当被import导入时,if块不会执行。这是Python惯用的模块入口模式。

四、dir()函数

4.1 查看模块内容

python
>>> import mymodule
>>> dir(mymodule)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'greet', 'PI']

4.2 查看当前命名空间

python
>>> dir()
['__builtins__', '__name__', ...]
>>> import mymodule
>>> dir()
['__builtins__', '__name__', 'mymodule']

五、包

5.1 包的结构

包是包含__init__.py文件的目录:

mypackage/
    __init__.py
    module1.py
    module2.py
    subpackage/
        __init__.py
        module3.py

__init__.py可以是空文件,也可以包含初始化代码。

5.2 导入包

python
import mypackage.module1
mypackage.module1.some_function()

from mypackage import module1
module1.some_function()

from mypackage.module1 import some_function
some_function()

5.3 init.py的作用

__init__.py在包被导入时执行,可以控制包的接口:

python
# mypackage/__init__.py
from .module1 import some_function
from .module2 import another_function

这样就可以直接从包导入:

python
from mypackage import some_function

六、相对导入

6.1 点号语法

在包内部,可以用相对导入:

python
# mypackage/module1.py
from . import module2           # 导入同包的module2
from .module2 import func       # 从module2导入func
from .. import top_module       # 导入上级包的模块
from ..other_package import mod # 导入兄弟包的模块

一个点.表示当前包,两个点..表示上级包。

6.2 注意事项

相对导入只能在包内使用,不能在顶层脚本中使用。如果模块被直接运行(__name__ == '__main__'),相对导入会失败。

七、标准库路径

7.1 常见位置

python
>>> import sys
>>> print(sys.prefix)          # Python安装目录
>>> print(sys.exec_prefix)     # 扩展模块目录

7.2 site-packages

第三方包安装在这里:

python
>>> import site
>>> site.getsitepackages()
['/usr/lib/python3.14/site-packages', ...]

八、包管理工具

8.1 pip

bash
# 安装包
pip install requests

# 指定版本
pip install requests==2.31.0

# 升级
pip install --upgrade requests

# 卸载
pip uninstall requests

# 查看已安装
pip list

# 导出依赖
pip freeze > requirements.txt

# 从文件安装
pip install -r requirements.txt

8.2 requirements.txt

requests==2.31.0
flask>=2.0
pandas~=2.0

版本约束:==精确匹配、>=大于等于、~=兼容版本。

九、虚拟环境

9.1 创建虚拟环境

bash
# 创建
python -m venv myenv

# 激活(Linux/macOS)
source myenv/bin/activate

# 激活(Windows)
myenv\Scripts\activate

# 退出
deactivate

9.2 为什么用虚拟环境

不同项目可能依赖不同版本的库。虚拟环境让每个项目有独立的依赖环境,互不干扰。

十、总结

概念说明
模块一个.py文件
包含__init__.py的目录
import导入模块
from...import从模块导入特定名称
__name__模块名,直接运行时为'__main__'
dir()查看模块或命名空间的内容
相对导入.当前包,..上级包
pip包管理工具
虚拟环境独立的依赖环境

if __name__ == '__main__'是模块入口的标准写法。虚拟环境是项目开发的标配,避免全局安装包。